<?php
/**
 * OptimizationRulesBetaApi
 * PHP version 5
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */

/**
 * Amazon Ads API for Sponsored Display
 *
 * This API enables programmatic access for campaign creation, management, and reporting for Sponsored Display campaigns. For more information on the functionality, see the [Sponsored Display Support Center](https://advertising.amazon.com/help#GTPPHE6RAWC2C4LZ). For API onboarding information, see the [account setup](https://advertising.amazon.com/API/docs/en-us/guides/onboarding/overview) topic.<br/><br/> > This specification is available for download from the **[Advertising API developer portal](https://d3a0d0y2hgofx6.cloudfront.net/openapi/en-us/sponsored-display/3-0/openapi.yaml).**
 *
 * OpenAPI spec version: 3.0
 * 
 * Generated by:https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api.git
 * AmazonAdvertisingApi Codegen version: 3.0.51
 */
/**
 * NOTE: This class is auto generated by the AmazonAdvertisingApi code generator program.
 *https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 * Do not edit the class manually.
 */

namespace AmazonAdvertisingApi\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use AmazonAdvertisingApi\ApiException;
use AmazonAdvertisingApi\Configuration;
use AmazonAdvertisingApi\HeaderSelector;
use AmazonAdvertisingApi\ObjectSerializer;

/**
 * OptimizationRulesBetaApi Class Doc Comment
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */
class OptimizationRulesBetaApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     */
    public function __construct(
        ClientInterface $client = null,
        Configuration $config = null,
        HeaderSelector $selector = null
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: new Configuration();
        $this->headerSelector = $selector ?: new HeaderSelector();
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation associateOptimizationRulesWithAdGroup
     *
     * Associate one or more optimization rules to an ad group specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateAssociatedOptimizationRulesRequest $body A list of optimization rule identifiers. Only one optimization rule identifier is currently supported per request. This note will be removed when multiple rule identifiers are supported.

For each ad group, only one optimization rule metric name is supported, based on the ad group&#x27;s &#x60;bidOptimization&#x60; type. Refer to the following table for the metric names supported for each type.
|  AdGroup.bidOptimization |     Supported OptimizationRule.metricName       |
|------------------|--------------------|
|   reach       | COST_PER_THOUSAND_VIEWABLE_IMPRESSIONS  |
|   clicks      | COST_PER_CLICK          |
|  conversions  | COST_PER_ORDER          | (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\OptimizationRuleResponse[]
     */
    public function associateOptimizationRulesWithAdGroup($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body = null)
    {
        list($response) = $this->associateOptimizationRulesWithAdGroupWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body);
        return $response;
    }

    /**
     * Operation associateOptimizationRulesWithAdGroupWithHttpInfo
     *
     * Associate one or more optimization rules to an ad group specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateAssociatedOptimizationRulesRequest $body A list of optimization rule identifiers. Only one optimization rule identifier is currently supported per request. This note will be removed when multiple rule identifiers are supported.

For each ad group, only one optimization rule metric name is supported, based on the ad group&#x27;s &#x60;bidOptimization&#x60; type. Refer to the following table for the metric names supported for each type.
|  AdGroup.bidOptimization |     Supported OptimizationRule.metricName       |
|------------------|--------------------|
|   reach       | COST_PER_THOUSAND_VIEWABLE_IMPRESSIONS  |
|   clicks      | COST_PER_CLICK          |
|  conversions  | COST_PER_ORDER          | (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\OptimizationRuleResponse[], HTTP status code, HTTP response headers (array of strings)
     */
    public function associateOptimizationRulesWithAdGroupWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]';
        $request = $this->associateOptimizationRulesWithAdGroupRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 207:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 422:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 500:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation associateOptimizationRulesWithAdGroupAsync
     *
     * Associate one or more optimization rules to an ad group specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateAssociatedOptimizationRulesRequest $body A list of optimization rule identifiers. Only one optimization rule identifier is currently supported per request. This note will be removed when multiple rule identifiers are supported.

For each ad group, only one optimization rule metric name is supported, based on the ad group&#x27;s &#x60;bidOptimization&#x60; type. Refer to the following table for the metric names supported for each type.
|  AdGroup.bidOptimization |     Supported OptimizationRule.metricName       |
|------------------|--------------------|
|   reach       | COST_PER_THOUSAND_VIEWABLE_IMPRESSIONS  |
|   clicks      | COST_PER_CLICK          |
|  conversions  | COST_PER_ORDER          | (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function associateOptimizationRulesWithAdGroupAsync($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body = null)
    {
        return $this->associateOptimizationRulesWithAdGroupAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation associateOptimizationRulesWithAdGroupAsyncWithHttpInfo
     *
     * Associate one or more optimization rules to an ad group specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateAssociatedOptimizationRulesRequest $body A list of optimization rule identifiers. Only one optimization rule identifier is currently supported per request. This note will be removed when multiple rule identifiers are supported.

For each ad group, only one optimization rule metric name is supported, based on the ad group&#x27;s &#x60;bidOptimization&#x60; type. Refer to the following table for the metric names supported for each type.
|  AdGroup.bidOptimization |     Supported OptimizationRule.metricName       |
|------------------|--------------------|
|   reach       | COST_PER_THOUSAND_VIEWABLE_IMPRESSIONS  |
|   clicks      | COST_PER_CLICK          |
|  conversions  | COST_PER_ORDER          | (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function associateOptimizationRulesWithAdGroupAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]';
        $request = $this->associateOptimizationRulesWithAdGroupRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'associateOptimizationRulesWithAdGroup'
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateAssociatedOptimizationRulesRequest $body A list of optimization rule identifiers. Only one optimization rule identifier is currently supported per request. This note will be removed when multiple rule identifiers are supported.

For each ad group, only one optimization rule metric name is supported, based on the ad group&#x27;s &#x60;bidOptimization&#x60; type. Refer to the following table for the metric names supported for each type.
|  AdGroup.bidOptimization |     Supported OptimizationRule.metricName       |
|------------------|--------------------|
|   reach       | COST_PER_THOUSAND_VIEWABLE_IMPRESSIONS  |
|   clicks      | COST_PER_CLICK          |
|  conversions  | COST_PER_ORDER          | (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function associateOptimizationRulesWithAdGroupRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id, $body = null)
    {
        // verify the required parameter 'amazon_advertising_api_client_id' is set
        if ($amazon_advertising_api_client_id === null || (is_array($amazon_advertising_api_client_id) && count($amazon_advertising_api_client_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_client_id when calling associateOptimizationRulesWithAdGroup'
            );
        }
        // verify the required parameter 'amazon_advertising_api_scope' is set
        if ($amazon_advertising_api_scope === null || (is_array($amazon_advertising_api_scope) && count($amazon_advertising_api_scope) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_scope when calling associateOptimizationRulesWithAdGroup'
            );
        }
        // verify the required parameter 'ad_group_id' is set
        if ($ad_group_id === null || (is_array($ad_group_id) && count($ad_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $ad_group_id when calling associateOptimizationRulesWithAdGroup'
            );
        }

        $resourcePath = '/sd/adGroups/{adGroupId}/optimizationRules';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($amazon_advertising_api_client_id !== null) {
            $headerParams['Amazon-Advertising-API-ClientId'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_client_id);
        }
        // header params
        if ($amazon_advertising_api_scope !== null) {
            $headerParams['Amazon-Advertising-API-Scope'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_scope);
        }

        // path params
        if ($ad_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'adGroupId' . '}',
                ObjectSerializer::toPathValue($ad_group_id),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createOptimizationRules
     *
     * Creates one or more optimization rules, also known as outcome optimizations.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify required fields and their values. Required fields are &#x60;state&#x60; and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\OptimizationRuleResponse[]
     */
    public function createOptimizationRules($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        list($response) = $this->createOptimizationRulesWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body);
        return $response;
    }

    /**
     * Operation createOptimizationRulesWithHttpInfo
     *
     * Creates one or more optimization rules, also known as outcome optimizations.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify required fields and their values. Required fields are &#x60;state&#x60; and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\OptimizationRuleResponse[], HTTP status code, HTTP response headers (array of strings)
     */
    public function createOptimizationRulesWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]';
        $request = $this->createOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 207:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 422:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 500:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation createOptimizationRulesAsync
     *
     * Creates one or more optimization rules, also known as outcome optimizations.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify required fields and their values. Required fields are &#x60;state&#x60; and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOptimizationRulesAsync($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        return $this->createOptimizationRulesAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation createOptimizationRulesAsyncWithHttpInfo
     *
     * Creates one or more optimization rules, also known as outcome optimizations.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify required fields and their values. Required fields are &#x60;state&#x60; and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOptimizationRulesAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]';
        $request = $this->createOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createOptimizationRules'
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\CreateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify required fields and their values. Required fields are &#x60;state&#x60; and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function createOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        // verify the required parameter 'amazon_advertising_api_client_id' is set
        if ($amazon_advertising_api_client_id === null || (is_array($amazon_advertising_api_client_id) && count($amazon_advertising_api_client_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_client_id when calling createOptimizationRules'
            );
        }
        // verify the required parameter 'amazon_advertising_api_scope' is set
        if ($amazon_advertising_api_scope === null || (is_array($amazon_advertising_api_scope) && count($amazon_advertising_api_scope) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_scope when calling createOptimizationRules'
            );
        }

        $resourcePath = '/sd/optimizationRules';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($amazon_advertising_api_client_id !== null) {
            $headerParams['Amazon-Advertising-API-ClientId'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_client_id);
        }
        // header params
        if ($amazon_advertising_api_scope !== null) {
            $headerParams['Amazon-Advertising-API-Scope'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_scope);
        }


        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listOptimizationRules
     *
     * Gets a list of optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $start_index Optional. Sets a cursor into the requested set of optimization rules. Use in conjunction with the &#x60;count&#x60; parameter to control pagination of the returned array. 0-indexed record offset for the result set, defaults to 0. (optional)
     * @param  int $count Optional. Sets the number of OptimizationRule objects in the returned array. Use in conjunction with the &#x60;startIndex&#x60; parameter to control pagination. For example, to return the first ten optimization rules set &#x60;startIndex&#x3D;0&#x60; and &#x60;count&#x3D;10&#x60;. To return the next ten optimization rules, set &#x60;startIndex&#x3D;10&#x60; and &#x60;count&#x3D;10&#x60;, and so on. Defaults to max page size. (optional)
     * @param  string $state_filter Optional. The returned array is filtered to include only optimization rules with state set to one of the values in the specified comma-delimited list. Available values:   - enabled   - paused [COMING LATER]   - enabled, paused [COMING LATER] (optional, default to enabled)
     * @param  string $name Optional. The returned array includes only optimization rules with the specified name using an exact string match. (optional)
     * @param  string $optimization_rule_id_filter Optional. The returned array is filtered to include only optimization rules associated with the optimization rule identifiers in the specified comma-delimited list.  Maximum size limit 50. (optional)
     * @param  string $ad_group_id_filter Optional. The returned array is filtered to include only optimization rules associated with the ad group identifiers in the comma-delimited list.  Maximum size limit 50. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\OptimizationRule[]
     */
    public function listOptimizationRules($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index = null, $count = null, $state_filter = 'enabled', $name = null, $optimization_rule_id_filter = null, $ad_group_id_filter = null)
    {
        list($response) = $this->listOptimizationRulesWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index, $count, $state_filter, $name, $optimization_rule_id_filter, $ad_group_id_filter);
        return $response;
    }

    /**
     * Operation listOptimizationRulesWithHttpInfo
     *
     * Gets a list of optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $start_index Optional. Sets a cursor into the requested set of optimization rules. Use in conjunction with the &#x60;count&#x60; parameter to control pagination of the returned array. 0-indexed record offset for the result set, defaults to 0. (optional)
     * @param  int $count Optional. Sets the number of OptimizationRule objects in the returned array. Use in conjunction with the &#x60;startIndex&#x60; parameter to control pagination. For example, to return the first ten optimization rules set &#x60;startIndex&#x3D;0&#x60; and &#x60;count&#x3D;10&#x60;. To return the next ten optimization rules, set &#x60;startIndex&#x3D;10&#x60; and &#x60;count&#x3D;10&#x60;, and so on. Defaults to max page size. (optional)
     * @param  string $state_filter Optional. The returned array is filtered to include only optimization rules with state set to one of the values in the specified comma-delimited list. Available values:   - enabled   - paused [COMING LATER]   - enabled, paused [COMING LATER] (optional, default to enabled)
     * @param  string $name Optional. The returned array includes only optimization rules with the specified name using an exact string match. (optional)
     * @param  string $optimization_rule_id_filter Optional. The returned array is filtered to include only optimization rules associated with the optimization rule identifiers in the specified comma-delimited list.  Maximum size limit 50. (optional)
     * @param  string $ad_group_id_filter Optional. The returned array is filtered to include only optimization rules associated with the ad group identifiers in the comma-delimited list.  Maximum size limit 50. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\OptimizationRule[], HTTP status code, HTTP response headers (array of strings)
     */
    public function listOptimizationRulesWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index = null, $count = null, $state_filter = 'enabled', $name = null, $optimization_rule_id_filter = null, $ad_group_id_filter = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRule[]';
        $request = $this->listOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index, $count, $state_filter, $name, $optimization_rule_id_filter, $ad_group_id_filter);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\OptimizationRule[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 422:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 500:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation listOptimizationRulesAsync
     *
     * Gets a list of optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $start_index Optional. Sets a cursor into the requested set of optimization rules. Use in conjunction with the &#x60;count&#x60; parameter to control pagination of the returned array. 0-indexed record offset for the result set, defaults to 0. (optional)
     * @param  int $count Optional. Sets the number of OptimizationRule objects in the returned array. Use in conjunction with the &#x60;startIndex&#x60; parameter to control pagination. For example, to return the first ten optimization rules set &#x60;startIndex&#x3D;0&#x60; and &#x60;count&#x3D;10&#x60;. To return the next ten optimization rules, set &#x60;startIndex&#x3D;10&#x60; and &#x60;count&#x3D;10&#x60;, and so on. Defaults to max page size. (optional)
     * @param  string $state_filter Optional. The returned array is filtered to include only optimization rules with state set to one of the values in the specified comma-delimited list. Available values:   - enabled   - paused [COMING LATER]   - enabled, paused [COMING LATER] (optional, default to enabled)
     * @param  string $name Optional. The returned array includes only optimization rules with the specified name using an exact string match. (optional)
     * @param  string $optimization_rule_id_filter Optional. The returned array is filtered to include only optimization rules associated with the optimization rule identifiers in the specified comma-delimited list.  Maximum size limit 50. (optional)
     * @param  string $ad_group_id_filter Optional. The returned array is filtered to include only optimization rules associated with the ad group identifiers in the comma-delimited list.  Maximum size limit 50. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listOptimizationRulesAsync($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index = null, $count = null, $state_filter = 'enabled', $name = null, $optimization_rule_id_filter = null, $ad_group_id_filter = null)
    {
        return $this->listOptimizationRulesAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index, $count, $state_filter, $name, $optimization_rule_id_filter, $ad_group_id_filter)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listOptimizationRulesAsyncWithHttpInfo
     *
     * Gets a list of optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $start_index Optional. Sets a cursor into the requested set of optimization rules. Use in conjunction with the &#x60;count&#x60; parameter to control pagination of the returned array. 0-indexed record offset for the result set, defaults to 0. (optional)
     * @param  int $count Optional. Sets the number of OptimizationRule objects in the returned array. Use in conjunction with the &#x60;startIndex&#x60; parameter to control pagination. For example, to return the first ten optimization rules set &#x60;startIndex&#x3D;0&#x60; and &#x60;count&#x3D;10&#x60;. To return the next ten optimization rules, set &#x60;startIndex&#x3D;10&#x60; and &#x60;count&#x3D;10&#x60;, and so on. Defaults to max page size. (optional)
     * @param  string $state_filter Optional. The returned array is filtered to include only optimization rules with state set to one of the values in the specified comma-delimited list. Available values:   - enabled   - paused [COMING LATER]   - enabled, paused [COMING LATER] (optional, default to enabled)
     * @param  string $name Optional. The returned array includes only optimization rules with the specified name using an exact string match. (optional)
     * @param  string $optimization_rule_id_filter Optional. The returned array is filtered to include only optimization rules associated with the optimization rule identifiers in the specified comma-delimited list.  Maximum size limit 50. (optional)
     * @param  string $ad_group_id_filter Optional. The returned array is filtered to include only optimization rules associated with the ad group identifiers in the comma-delimited list.  Maximum size limit 50. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listOptimizationRulesAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index = null, $count = null, $state_filter = 'enabled', $name = null, $optimization_rule_id_filter = null, $ad_group_id_filter = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRule[]';
        $request = $this->listOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index, $count, $state_filter, $name, $optimization_rule_id_filter, $ad_group_id_filter);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'listOptimizationRules'
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $start_index Optional. Sets a cursor into the requested set of optimization rules. Use in conjunction with the &#x60;count&#x60; parameter to control pagination of the returned array. 0-indexed record offset for the result set, defaults to 0. (optional)
     * @param  int $count Optional. Sets the number of OptimizationRule objects in the returned array. Use in conjunction with the &#x60;startIndex&#x60; parameter to control pagination. For example, to return the first ten optimization rules set &#x60;startIndex&#x3D;0&#x60; and &#x60;count&#x3D;10&#x60;. To return the next ten optimization rules, set &#x60;startIndex&#x3D;10&#x60; and &#x60;count&#x3D;10&#x60;, and so on. Defaults to max page size. (optional)
     * @param  string $state_filter Optional. The returned array is filtered to include only optimization rules with state set to one of the values in the specified comma-delimited list. Available values:   - enabled   - paused [COMING LATER]   - enabled, paused [COMING LATER] (optional, default to enabled)
     * @param  string $name Optional. The returned array includes only optimization rules with the specified name using an exact string match. (optional)
     * @param  string $optimization_rule_id_filter Optional. The returned array is filtered to include only optimization rules associated with the optimization rule identifiers in the specified comma-delimited list.  Maximum size limit 50. (optional)
     * @param  string $ad_group_id_filter Optional. The returned array is filtered to include only optimization rules associated with the ad group identifiers in the comma-delimited list.  Maximum size limit 50. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function listOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $start_index = null, $count = null, $state_filter = 'enabled', $name = null, $optimization_rule_id_filter = null, $ad_group_id_filter = null)
    {
        // verify the required parameter 'amazon_advertising_api_client_id' is set
        if ($amazon_advertising_api_client_id === null || (is_array($amazon_advertising_api_client_id) && count($amazon_advertising_api_client_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_client_id when calling listOptimizationRules'
            );
        }
        // verify the required parameter 'amazon_advertising_api_scope' is set
        if ($amazon_advertising_api_scope === null || (is_array($amazon_advertising_api_scope) && count($amazon_advertising_api_scope) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_scope when calling listOptimizationRules'
            );
        }

        $resourcePath = '/sd/optimizationRules';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        if ($start_index !== null) {
            $queryParams['startIndex'] = ObjectSerializer::toQueryValue($start_index, 'int32');
        }
        // query params
        if ($count !== null) {
            $queryParams['count'] = ObjectSerializer::toQueryValue($count, 'int32');
        }
        // query params
        if ($state_filter !== null) {
            $queryParams['stateFilter'] = ObjectSerializer::toQueryValue($state_filter, null);
        }
        // query params
        if ($name !== null) {
            $queryParams['name'] = ObjectSerializer::toQueryValue($name, null);
        }
        // query params
        if ($optimization_rule_id_filter !== null) {
            $queryParams['optimizationRuleIdFilter'] = ObjectSerializer::toQueryValue($optimization_rule_id_filter, null);
        }
        // query params
        if ($ad_group_id_filter !== null) {
            $queryParams['adGroupIdFilter'] = ObjectSerializer::toQueryValue($ad_group_id_filter, null);
        }
        // header params
        if ($amazon_advertising_api_client_id !== null) {
            $headerParams['Amazon-Advertising-API-ClientId'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_client_id);
        }
        // header params
        if ($amazon_advertising_api_scope !== null) {
            $headerParams['Amazon-Advertising-API-Scope'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_scope);
        }


        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation sdAdGroupsAdGroupIdOptimizationRulesGet
     *
     * Gets a list of optimization rules associated to an adgroup specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\OptimizationRule[]
     */
    public function sdAdGroupsAdGroupIdOptimizationRulesGet($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id)
    {
        list($response) = $this->sdAdGroupsAdGroupIdOptimizationRulesGetWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id);
        return $response;
    }

    /**
     * Operation sdAdGroupsAdGroupIdOptimizationRulesGetWithHttpInfo
     *
     * Gets a list of optimization rules associated to an adgroup specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\OptimizationRule[], HTTP status code, HTTP response headers (array of strings)
     */
    public function sdAdGroupsAdGroupIdOptimizationRulesGetWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRule[]';
        $request = $this->sdAdGroupsAdGroupIdOptimizationRulesGetRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\OptimizationRule[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 500:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation sdAdGroupsAdGroupIdOptimizationRulesGetAsync
     *
     * Gets a list of optimization rules associated to an adgroup specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function sdAdGroupsAdGroupIdOptimizationRulesGetAsync($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id)
    {
        return $this->sdAdGroupsAdGroupIdOptimizationRulesGetAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation sdAdGroupsAdGroupIdOptimizationRulesGetAsyncWithHttpInfo
     *
     * Gets a list of optimization rules associated to an adgroup specified by identifier.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function sdAdGroupsAdGroupIdOptimizationRulesGetAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRule[]';
        $request = $this->sdAdGroupsAdGroupIdOptimizationRulesGetRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'sdAdGroupsAdGroupIdOptimizationRulesGet'
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  int $ad_group_id The identifier of the ad group. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function sdAdGroupsAdGroupIdOptimizationRulesGetRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $ad_group_id)
    {
        // verify the required parameter 'amazon_advertising_api_client_id' is set
        if ($amazon_advertising_api_client_id === null || (is_array($amazon_advertising_api_client_id) && count($amazon_advertising_api_client_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_client_id when calling sdAdGroupsAdGroupIdOptimizationRulesGet'
            );
        }
        // verify the required parameter 'amazon_advertising_api_scope' is set
        if ($amazon_advertising_api_scope === null || (is_array($amazon_advertising_api_scope) && count($amazon_advertising_api_scope) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_scope when calling sdAdGroupsAdGroupIdOptimizationRulesGet'
            );
        }
        // verify the required parameter 'ad_group_id' is set
        if ($ad_group_id === null || (is_array($ad_group_id) && count($ad_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $ad_group_id when calling sdAdGroupsAdGroupIdOptimizationRulesGet'
            );
        }

        $resourcePath = '/sd/adGroups/{adGroupId}/optimizationRules';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($amazon_advertising_api_client_id !== null) {
            $headerParams['Amazon-Advertising-API-ClientId'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_client_id);
        }
        // header params
        if ($amazon_advertising_api_scope !== null) {
            $headerParams['Amazon-Advertising-API-Scope'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_scope);
        }

        // path params
        if ($ad_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'adGroupId' . '}',
                ObjectSerializer::toPathValue($ad_group_id),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation sdOptimizationRulesOptimizationRuleIdGet
     *
     * Gets a requested optimization rule.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  string $optimization_rule_id The identifier of the requested optimization rule. (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\OptimizationRule
     */
    public function sdOptimizationRulesOptimizationRuleIdGet($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id)
    {
        list($response) = $this->sdOptimizationRulesOptimizationRuleIdGetWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id);
        return $response;
    }

    /**
     * Operation sdOptimizationRulesOptimizationRuleIdGetWithHttpInfo
     *
     * Gets a requested optimization rule.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  string $optimization_rule_id The identifier of the requested optimization rule. (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\OptimizationRule, HTTP status code, HTTP response headers (array of strings)
     */
    public function sdOptimizationRulesOptimizationRuleIdGetWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRule';
        $request = $this->sdOptimizationRulesOptimizationRuleIdGetRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\OptimizationRule',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 500:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation sdOptimizationRulesOptimizationRuleIdGetAsync
     *
     * Gets a requested optimization rule.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  string $optimization_rule_id The identifier of the requested optimization rule. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function sdOptimizationRulesOptimizationRuleIdGetAsync($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id)
    {
        return $this->sdOptimizationRulesOptimizationRuleIdGetAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation sdOptimizationRulesOptimizationRuleIdGetAsyncWithHttpInfo
     *
     * Gets a requested optimization rule.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  string $optimization_rule_id The identifier of the requested optimization rule. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function sdOptimizationRulesOptimizationRuleIdGetAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRule';
        $request = $this->sdOptimizationRulesOptimizationRuleIdGetRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'sdOptimizationRulesOptimizationRuleIdGet'
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  string $optimization_rule_id The identifier of the requested optimization rule. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function sdOptimizationRulesOptimizationRuleIdGetRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $optimization_rule_id)
    {
        // verify the required parameter 'amazon_advertising_api_client_id' is set
        if ($amazon_advertising_api_client_id === null || (is_array($amazon_advertising_api_client_id) && count($amazon_advertising_api_client_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_client_id when calling sdOptimizationRulesOptimizationRuleIdGet'
            );
        }
        // verify the required parameter 'amazon_advertising_api_scope' is set
        if ($amazon_advertising_api_scope === null || (is_array($amazon_advertising_api_scope) && count($amazon_advertising_api_scope) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_scope when calling sdOptimizationRulesOptimizationRuleIdGet'
            );
        }
        // verify the required parameter 'optimization_rule_id' is set
        if ($optimization_rule_id === null || (is_array($optimization_rule_id) && count($optimization_rule_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $optimization_rule_id when calling sdOptimizationRulesOptimizationRuleIdGet'
            );
        }

        $resourcePath = '/sd/optimizationRules/{optimizationRuleId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($amazon_advertising_api_client_id !== null) {
            $headerParams['Amazon-Advertising-API-ClientId'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_client_id);
        }
        // header params
        if ($amazon_advertising_api_scope !== null) {
            $headerParams['Amazon-Advertising-API-Scope'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_scope);
        }

        // path params
        if ($optimization_rule_id !== null) {
            $resourcePath = str_replace(
                '{' . 'optimizationRuleId' . '}',
                ObjectSerializer::toPathValue($optimization_rule_id),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOptimizationRules
     *
     * Updates one or more optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\UpdateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify an optimization rule identifier and mutable fields with their updated values. The mutable fields are &#x60;ruleName&#x60;, &#x60;state&#x60;, and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\OptimizationRuleResponse[]
     */
    public function updateOptimizationRules($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        list($response) = $this->updateOptimizationRulesWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body);
        return $response;
    }

    /**
     * Operation updateOptimizationRulesWithHttpInfo
     *
     * Updates one or more optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\UpdateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify an optimization rule identifier and mutable fields with their updated values. The mutable fields are &#x60;ruleName&#x60;, &#x60;state&#x60;, and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\OptimizationRuleResponse[], HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOptimizationRulesWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]';
        $request = $this->updateOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 207:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 422:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 500:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation updateOptimizationRulesAsync
     *
     * Updates one or more optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\UpdateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify an optimization rule identifier and mutable fields with their updated values. The mutable fields are &#x60;ruleName&#x60;, &#x60;state&#x60;, and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOptimizationRulesAsync($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        return $this->updateOptimizationRulesAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation updateOptimizationRulesAsyncWithHttpInfo
     *
     * Updates one or more optimization rules.
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\UpdateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify an optimization rule identifier and mutable fields with their updated values. The mutable fields are &#x60;ruleName&#x60;, &#x60;state&#x60;, and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOptimizationRulesAsyncWithHttpInfo($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\OptimizationRuleResponse[]';
        $request = $this->updateOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOptimizationRules'
     *
     * @param  string $amazon_advertising_api_client_id The identifier of a client associated with a \&quot;Login with Amazon\&quot; account. (required)
     * @param  string $amazon_advertising_api_scope The identifier of a profile associated with the advertiser account. Use &#x60;GET&#x60; method on Profiles resource to list profiles associated with the access token passed in the HTTP Authorization header. (required)
     * @param  \AmazonAdvertisingApi\Model\UpdateOptimizationRule[] $body An array of OptimizationRule objects. For each object, specify an optimization rule identifier and mutable fields with their updated values. The mutable fields are &#x60;ruleName&#x60;, &#x60;state&#x60;, and &#x60;ruleConditions&#x60;. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function updateOptimizationRulesRequest($amazon_advertising_api_client_id, $amazon_advertising_api_scope, $body = null)
    {
        // verify the required parameter 'amazon_advertising_api_client_id' is set
        if ($amazon_advertising_api_client_id === null || (is_array($amazon_advertising_api_client_id) && count($amazon_advertising_api_client_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_client_id when calling updateOptimizationRules'
            );
        }
        // verify the required parameter 'amazon_advertising_api_scope' is set
        if ($amazon_advertising_api_scope === null || (is_array($amazon_advertising_api_scope) && count($amazon_advertising_api_scope) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_advertising_api_scope when calling updateOptimizationRules'
            );
        }

        $resourcePath = '/sd/optimizationRules';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($amazon_advertising_api_client_id !== null) {
            $headerParams['Amazon-Advertising-API-ClientId'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_client_id);
        }
        // header params
        if ($amazon_advertising_api_scope !== null) {
            $headerParams['Amazon-Advertising-API-Scope'] = ObjectSerializer::toHeaderValue($amazon_advertising_api_scope);
        }


        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        return $options;
    }
}
